﻿using System;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace T.FAS.Runtime.Base.Entity
{
    [JsonConverter(typeof(TimestampJsonConverter))]
    public class Timestamp
    {
        /// <summary>
        /// Timestamp默认Format格式
        /// </summary>
        public const string DefaultTimeFormat = "yyyy-MM-dd HH:mm:ss.fff";

        /// <summary>
        /// DateTime类型数据，真正接收DB返回的时间数据，受SG框架Json序列化影响
        /// </summary>
        [JsonIgnore]
        public DateTime Value { get; set; }
        /// <summary>
        /// String类型数据，构造TResult时，将Value值根据Format格式转化的字符串数据，不受SG框架Json序列化影响
        /// </summary>
        public string Data { get; set; }
        /// <summary>
        /// Format格式，指示Value转化为时间的Format格式
        /// </summary>
        public string Format { get; set; }

        public override string ToString()
        {
            return string.IsNullOrEmpty(Format) ? Value.ToString(DefaultTimeFormat) : Value.ToString(Format);
        }

        public string ToString(string format)
        {
            return Value.ToString(format);
        }
    }

    public class TimestampJsonConverter : JsonConverter
    {

        public override bool CanRead => true;

        public override bool CanWrite => true;

        public override bool CanConvert(Type objectType)
        {
            return typeof(Timestamp) == objectType;
        }

        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            JObject jObj = serializer.Deserialize<JObject>(reader);
            return GetTimestamp(jObj);
        }

        public Timestamp GetTimestamp(JObject jObj)
        {
            try
            {
                Timestamp timestamp = new Timestamp();
                timestamp.Data = jObj.Value<string>("Data");
                timestamp.Format = jObj.Value<string>("Format");
                timestamp.Value = Convert.ToDateTime(timestamp.Data);
                if (string.IsNullOrEmpty(timestamp.Format))
                {
                    timestamp.Format = Timestamp.DefaultTimeFormat;
                }
                return timestamp;
            }
            catch (Exception e)
            {
                throw new Exception($"timestamp convert failed:{jObj}", e);
            }
        }

        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            writer.WriteStartObject();
            if (value is Timestamp timestamp)
            {
                var format = string.IsNullOrEmpty(timestamp.Format) ? Timestamp.DefaultTimeFormat : timestamp.Format;
                writer.WritePropertyName("Data"); writer.WriteValue(timestamp.Value.ToString(format));
                writer.WritePropertyName("Value"); writer.WriteValue(timestamp.Value);
                writer.WritePropertyName("Format"); writer.WriteValue(format);
            }
            writer.WriteEndObject();
        }
    }
}